<?php

namespace app\common\model;

use org\util\TreeUtil;
use think\Db;
use think\Validate;

class UserModel extends BaseModel
{
    protected $name = 'user'; //定义用户表
    //开启自动写入时间戳
    protected $autoWriteTimestamp = true;
    // 定义自动完成的属性
    protected $auto = []; //新增修改
    protected $insert = []; //插入
    protected $update = []; //修改
    //类型自动转换
    protected $type = [
        'dept_ids' => 'array'
    ];

    //设置用户密码
    protected function setPasswordAttr($value)
    {
        return md5(sha1($value));
    }

    /**
     * 添加用户
     * @param $data
     * @return bool
     */
    public function addData($data)
    {
        try {
            if (empty($data['username']) && empty($data['mobile']) && empty($data['email'])) {
                exception('用户名/手机号/邮箱至少应该填写一个', 40001);
            }
            if (!empty($data['username'])) {
                if ($this->isUserName($data['username']) === false) {
                    exception('用户名格式错误', 40001);
                }
                if ($this->where('username', $data['username'])->find()) {
                    exception('该用户已存在', 40001);
                }
            }
            if (!empty($data['mobile'])) {
                if ($this->isMobile($data['mobile']) === false) {
                    exception('手机号格式不正确', 40001);
                }
                if ($this->where('mobile', $data['mobile'])->find()) {
                    exception('该手机号已注册', 40001);
                }
            }
            if (!empty($data['email'])) {
                if ($this->isEmail($data['email']) === false) {
                    exception('email格式不正确', 40001);
                }
                if ($this->where('email', $data['email'])->find()) {
                    exception('该邮箱已注册', 40001);
                }
            }
            //日期字段置空
            if (empty($data['birthday'])) {
                $data['birthday'] = null;
            }
            $this->isUpdate(false)->allowField(true)->save($data);
            return $this->getData('uid');
        } catch (\Exception $e) {
            exception($e->getMessage(), 40001);
        }
    }

    /**
     * 编辑用户
     * @param $data
     * @return bool
     */
    public function editData($data)
    {
        try {
            if (empty($data['password'])) {
                unset($data['password']);
            }
            $info = $this->get($data['uid']);
            if (!empty($data['username'])) {
                if ($info['username'] != $data['username']) {
                    if ($this->isUserName($data['username']) === false) {
                        exception('用户名格式错误', 40001);
                    }
                    if ($this->where('username', $data['username'])->find()) {
                        exception('该用户已存在！', 40001);
                    }
                }
            }
            if (!empty($data['mobile'])) {
                if ($info['mobile'] != $data['mobile']) {
                    if ($this->isMobile($data['mobile']) === false) {
                        exception('手机号格式错误！', 40001);
                    }
                    if ($this->where('mobile', $data['mobile'])->find()) {
                        exception('该手机号已注册！', 40001);
                    }
                }
            }
            if (!empty($data['email'])) {
                if ($info['email'] != $data['email']) {
                    if ($this->isEmail($data['email']) === false) {
                        exception('email格式错误！', 40001);
                    }
                    if ($this->where('email', $data['email'])->find()) {
                        exception('该邮箱已注册！', 40001);
                    }
                }
            }
            if ($info['uid'] == 1) $data['status'] = 1; //系统管理员不允许禁用
            if (empty($data['birthday'])) {
                $data['birthday'] = null;
            }
            $this->isUpdate(true)->allowField(true)->save($data);
            return $this->getData('uid');
        } catch (\Exception $e) {
            exception($e->getMessage(), 40001);
        }
    }

    /**
     * 设置用户状态
     * @param $uid
     * @return bool
     */
    public function setStatus($uid)
    {
        try {
            if ($uid == 1) {
                exception('系统管理员不允许禁用', 40001);
            }
            $status = $this->where('uid', $uid)->value('status');
            $status = $status == 1 ? 0 : 1;
            $this->where('uid', $uid)->setField('status', $status);
            Db::table('car_driver')->where('bind_uid',$uid)->setField('work_status',$status);
            return true;
        } catch (\Exception $e) {
            exception($e->getMessage(), 40001);
        }

    }

    /**
     * 检测用户登录
     * @param $account
     * @param $password
     * @return bool
     */
    public function checkLogin($account, $password, $utype = "system")
    {
        try {
            $field = $this->checkUserName($account);
            if (empty($field)) {
                exception('帐户信息有误', 40001);
            }
            $user = $this->where($field, $account)->where('utype', $utype)->find();
            if (empty($user)) {
                exception('用户不存在', 40001);
            }
            if ($user->getData('password') == md5(sha1($password))) {
                $status = $user->getData('status');
                $uid = $user->getData('uid');
                $deptIds = $user->getAttr('dept_ids');
                if(empty($deptIds)){
                    $deptIds='';
                }else{
                    $deptIds=implode(',',$deptIds);
                }
                if ($status == 1) {
                    $loginData = [
                        'last_login_time' => time(),
                        'last_login_ip' => get_client_ip(),
                        'login_times' => $user->getData('login_times') + 1,
                    ];
                    $this->where('uid', $uid)->update($loginData);
                    $token = config('base.login_token');
                    $des = str_encode($uid . $token . $utype . $token . $deptIds);
                    return $des;
                }
                exception('该用户已锁定', 40001);
            }
            exception('密码输入错误', 40001);
        } catch (\Exception $e) {
            exception($e->getMessage(), 40001);
        }
    }

    /**
     * 获取用户权限
     * @param $uid
     * @param $utype
     * @return array
     */
    public function getMyRuleList($groupId, $utype)
    {
        try {
            $ruleList = cache('auth_rule_' . $utype); //全部权限
            if (empty($ruleList)) { //重新缓存
                $model = new AuthRuleModel();
                $model->updateCache($utype);
                $ruleList = cache('auth_rule_' . $utype);
            }
            $myRuleList=[];
            //超管权限
            if($groupId==1001){
                $myRuleList = $ruleList;
            }else{
                //当前groupid拥有权限
                $authGroupRuleModel = new AuthGroupRuleModel();
                $rules = $authGroupRuleModel->where('group_id',$groupId)->column('rule_button','rule_id');
                if (empty($rules)) {
                    return [];
                }
                $myruleid = array_keys($rules);
                foreach ($ruleList as $k => $v) {
                    if (in_array($k, $myruleid)) {
                        $v['rule_button']=$rules[$k]; //替换button
                        $myRuleList[$k] = $v;
                    }
                }
            }
            $treeRule = TreeUtil::channelLevel($myRuleList, 0, "&nbsp;", 'rule_id', 'rule_pid');
            return $treeRule;
        } catch (\Exception $e) {
            exception($e->getMessage(), 40001);
        }
    }

    /**
     * @param $account
     * 检测用户名
     */
    public function checkUserName($account)
    {
        if ($this->isUserName($account)) {
            return 'username';
        }
        if ($this->isMobile($account)) {
            return 'mobile';
        }
        if ($this->isEmail($account)) {
            return 'email';
        }
        return '';
    }

    /**
     * 是否用户名
     * @param $username
     * @return bool
     */
    public function isUserName($username)
    {
        $valid = Validate::regex($username, '/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){3,19}$/');
        if ($valid) {
            return true;
        } else {
            $this->error = '用户名只能为字母和数字且必须以字母开头';
            return false;
        }
    }

    /**
     * 是否手机号
     */
    public function isMobile($mobile)
    {
        $valid = Validate::regex($mobile, '/^1[3456789]{1}\d{9}$/');
        if ($valid) {
            return true;
        } else {
            $this->error = '手机号格式不正确';
            return false;
        }
    }

    /**
     * 是否邮箱
     */
    public function isEmail($email)
    {
        $valid = Validate::is($email, 'email');
        if ($valid) {
            return true;
        } else {
            $this->error = '手机号格式不正确';
            return false;
        }
    }

    /**
     * 按权限读取列表
     */
    public function getOp($op,$uid,$myDeptId)
    {
        $map = [];
        if ($op == 1) { //查看自己的文档
            $map['uid'] = $uid;
        }
        if ($op == 2) { //查看自己所在部门及所有下级的文档
            $deptCache = cache('dept');
            $deptModel = new DeptModel();
            $deptList = $deptModel->where('dept_id','in',$myDeptId)->select();
            //echo $deptModel->getLastSql();
            $deptIds = [];
            if(!$deptList->isEmpty()){
                foreach($deptList as $v){
                    if($v['dept_uid']==$uid){ //如果是部门主管
                        $childDeptids = array_keys(\org\util\TreeUtil::channelList($deptCache, $v['dept_id'], "&nbsp;", 'dept_id', 'dept_fid'));
                        $childDeptids[]=$v['dept_id'];
                        foreach($childDeptids as $deptid){
                            $deptIds[]=$deptid;
                        }
                    }
                }
                if(!empty($deptIds)){
                    $deptIds = implode(',',$deptIds);
                    $map['dept_id'] = ["exp"," in ({$deptIds}) or uid={$uid}"];
                }
            }
        }
        if(!empty($op)){
            //u:1,2,3,4 //用户ID组
            //d:1,2,3,4 //部门ID组
            $op = explode(':',$op);
            if($op=='u'){
                $map['uid']=['in',$op[1]];
            }
            if($op=='d'){
                $map['dept_id']=['in',$op[1]];
            }
        }
        return $map;
    }
}